//: src/com/silvtar/sync/model/SSTreeNode.java
/* 
 * Created by 朴晟宁 <piaosn@gmail.com> on 4/21/2013. 
 * Copyright (c) 2013 朴晟宁. All rights reserved.
 * 
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program;
 * 
 * *********************************************************************
 * 
 * Modify History:
 * Date        Version    Description
 * 4/20/2013   0.1        Create the class
 * 4/23/2013   0.1.1      Add a variable named MD5  
 * 5/11/2013   0.3        Serializable
 */
package com.silvtar.sync.model;

import java.io.IOException;
import java.io.Serializable;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Date;

import com.silvtar.io.StdOut;
import com.silvtar.io.StreamToolkit;

/**
 * 文件树节点类 本类为文件树中的节点，即代表了文件夹或文件。 本类中保存有文件属性
 * 但本类不能单独使用，本类中不包含绝对路径，所以无法单独通过本类对象定位到文件本身
 * 
 * @author 朴晟宁/Silvtar
 * @author piaosn@gmail.com
 * @version 0.3
 */
public class SSTreeNode implements Serializable {

    /**
     * 
     */
    private static final long     serialVersionUID = 1L;

    private String                name             = null; // 文件名

    private String                relativePath     = null; // 相对路径
                                                            // 即相对于同步根目录的相对路径

    private boolean               dir              = false; // 本节点是否为文件夹

    private Date                  date             = null; // 最后修改时间

    private long                  size             = 0;    // 文件大小

    private String                md5              = null; // 文件的MD5校验值，仅当节点为文件时有效

    private ArrayList<SSTreeNode> child            = null; // 子节点列表
                                                            // 只有在本节点为文件夹时有效

    // ---------------------------- getter && setter ---------------------------

    public String getName() {

        return name;
    }

    public void setName(String name) {

        this.name = name;
    }

    public String getMd5() {

        return md5;
    }

    public void setMd5(String md5) {

        this.md5 = md5;
    }

    public String getRelativePath() {

        return relativePath;
    }

    public void setRelativePath(String relativePath) {

        this.relativePath = relativePath;
    }

    public boolean isDir() {

        return dir;
    }

    public ArrayList<SSTreeNode> getChild() {

        return child;
    }

    public void setChild(ArrayList<SSTreeNode> child) {

        this.child = child;
    }

    public void setDir(boolean isDir) {

        this.dir = isDir;
    }

    public Date getDate() {

        return date;
    }

    public void setDate(Date date) {

        this.date = date;
    }

    public long getSize() {

        return size;
    }

    public void setSize(long size) {

        this.size = size;
    }

    // --------------------------------- 构造方法 --------------------------------
    public SSTreeNode() {

        // TODO Auto-generated constructor stub
        child = new ArrayList<SSTreeNode>();
    }

    @Override
    public int hashCode() {

        final int prime = 31;
        int result = 1;
        result = prime * result + ((child == null) ? 0 : child.hashCode());
        result = prime * result + ((date == null) ? 0 : date.hashCode());
        result = prime * result + (dir ? 1231 : 1237);
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        result = prime * result
                + ((relativePath == null) ? 0 : relativePath.hashCode());
        result = prime * result + (int) (size ^ (size >>> 32));
        return result;
    }

    /**
     * 在判断时仅仅查看文件名。
     */
    @Override
    public boolean equals(Object obj) {

        if (this == obj)
            return true;
        if (obj == null)
            return false;

        SSTreeNode other = (SSTreeNode) obj;

        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;

        return true;
    }

    // --------------------------------- 主要方法 --------------------------------

    /**
     * 打印函数，递归运行。 本函数向输出设备中输出本节点的文件名，并调用所有子节点的print函数。
     */
    public void print() {

        for (int i = 0; i < child.size(); i++) {
            StdOut.println(child.get(i).getRelativePath() + child.get(i).getName());
            if (child.get(i).isDir())
                child.get(i).print();
        }
        
    }

    public void printXML() {
        Writer writer = new StreamToolkit("filetree.xml").getWriter();
        try {
            writer.write("test ");
            writer.write("test1 ");
            writer.write("test2 ");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
